<template>
  <div class="tools-container">
    <!-- 基本配置 -->
    <a-row class="tabs-mrt">
      <a-col :span="22">
        <a-collapse :default-active-key="[1]" accordion>
          <a-collapse-item header="服务器配置" key="1">
            <a-col :span="22">
              <a-tabs :editable="true" @add="handleAdd" @delete="handleDelete" show-add-button auto-switch>
                <a-tab-pane v-for="(item, index) of serveData" :key="item.key" :title="item.title">
                  <a-col class="tabs-mrt">
                    <a-input :style="{ width: '310px' }" v-model="item.title" placeholder="为该服务器起个名" allow-clear />
                  </a-col>
                  <a-col class="tabs-mrt">
                    <a-space>
                      <a-input :style="{ width: '200px' }" v-model="item.ip" placeholder="请输入IP" allow-clear />
                      <a-input :style="{ width: '100px' }" v-model="item.port" placeholder="请输入端口" allow-clear />
                    </a-space>
                  </a-col>
                  <a-col class="tabs-mrt">
                    <a-input :style="{ width: '310px' }" v-model="item.username" placeholder="请输入账号" allow-clear />
                  </a-col>
                  <a-col class="tabs-mrt">
                    <a-input-password :style="{ width: '310px' }" v-model="item.password" placeholder="请输入密码"
                      allow-clear />
                  </a-col>
                  <a-col class="tabs-mrt">
                    <a-button type="primary" @click="testCon">
                      <template #icon>
                        <icon-robot />
                      </template>
                      <template #default>测试连接</template>
                    </a-button>
                  </a-col>
                  <a-col class="tabs-mrt" :span="22">
                    <span>部署路径：</span>
                    <a-input v-model="item.serverPath" :style="{ width: '310px' }"
                      placeholder="请输入部署路径，例如：/home/lcpt60/app/" allow-clear />
                  </a-col>
                  <a-col class="tabs-mrt" :span="9">
                    <a-collapse :default-active-key="[1]" accordion>
                      <a-collapse-item header="配置路径说明" key="1">
                        <pre>
指定到服务部署级别即可，例如部署结构为：
-- home
  -- lcpt60
    -- app
      -- lcpt-fina-api</pre>
                        则部署路径为：<a-tag color="red">/home/lcpt60/app/</a-tag>
                      </a-collapse-item>
                    </a-collapse>
                  </a-col>
                  <a-col class="tabs-mrt">
                    <span>选择部署的服务：</span>
                    <a-select :style="{ width: '310px' }" v-model="item.server" placeholder="选择部署的服务" multiple
                      allow-clear>
                      <a-option v-for="(item, index) in serves">{{
                        item
                      }}</a-option>
                      <template #header>
                        <div style="padding: 6px 12px">
                          <a-checkbox value="1">全选</a-checkbox>
                        </div>
                      </template>
                    </a-select>
                  </a-col>
                </a-tab-pane>
              </a-tabs>
            </a-col>
            <a-col :span="22" class="tabs-mrt">
              <a-button type="primary" @click="saveCon">
                <template #icon>
                  <icon-save />
                </template>
                <template #default>保存配置</template>
              </a-button>
            </a-col>
          </a-collapse-item>
          <a-collapse-item header="启动脚本配置" key="3">
            <span>选择启停模式： </span>
            <a-select v-model="selectMode" :style="{ width: '320px' }" placeholder="请选择启停模式">
              <a-option value="stop">stop.sh</a-option>
              <a-option value="start">start.sh</a-option>
              <a-option value="normal">stop.sh&start.sh</a-option>
              <a-option value="restart">restart.sh</a-option>
            </a-select>
            <p><b>stop.sh 模式：</b>分别调用停止脚本，对程序进行停止</p>
            <p><b>start.sh 模式：</b>分别调用启动脚本，对程序进行启动</p>
            <p>
              <b>stop.sh&start.sh 模式：</b>分别调用停止和启动脚本，对程序进行重启
            </p>
            <p>
              <b>restart.sh 模式：</b>直接调用重启脚本，请确认服务启动目录有该脚本
            </p>
          </a-collapse-item>
          <a-collapse-item header="注册中心配置" key="4">
            <a-col class="tabs-mrt">
              <a-space>
                <span>使用注册中心:</span>
                <a-select v-model="registerData.name" :style="{ width: '310px' }" placeholder="请选择使用的注册中心">
                  <a-option value="eurka">Eurka</a-option>
                  <a-option value="consul">Consul</a-option>
                  <a-option disabled value="nacos">Nacos</a-option>
                  <a-option disabled value="zookeeper">Zookeeper</a-option>
                </a-select>
              </a-space>
            </a-col>
            <a-col class="tabs-mrt">
              <a-space>
                <span>注册中心地址:</span>
                <a-input :style="{ width: '310px' }" v-model="registerData.url" placeholder="请输入注册中心地址" allow-clear />
              </a-space>
              <a-col :span="10">
                <a-collapse class="tabs-mrt" :default-active-key="[1]" accordion>
                  <a-collapse-item header="配置注意！" key="1">
                    <div>
                      <p>
                        必须配置spring.application.name=
                        和服务名一致，否则接口传参的注册服务名可能错误
                      </p>
                      <p>
                        例如：部署的服务是：<a-tag color="red">lcpt-fina-api</a-tag>，则 spring.application.name=<a-tag
                          color="red">lcpt-fina-api</a-tag>
                      </p>
                      <p>且必须：eureka.instance.prefer-ip-address: true</p>
                      <p>
                        填写示范：<a-tag color="red">http://127.0.0.1:8091/</a-tag>
                      </p>
                    </div>
                  </a-collapse-item>
                </a-collapse>
              </a-col>
            </a-col>
            <a-col :span="22" class="tabs-mrt">
              <a-button type="primary" @click="saveRegister">
                <template #icon>
                  <icon-save />
                </template>
                <template #default>保存配置</template>
              </a-button>
            </a-col>
          </a-collapse-item>
          <a-collapse-item header="启停服务选择" key="5">
            <a-col class="tabs-mrt">
              <a-select :style="{ width: '310px' }" @change="changeRestartSer" v-model="restartServeData"
                placeholder="选择启停的的服务" multiple allow-clear>
                <a-option v-for="(item, index) in serves">{{ item }}</a-option>
                <template #header>
                  <div style="padding: 6px 12px">
                    <a-checkbox @click="selectAllRestartSer" value="1">全选</a-checkbox>
                  </div>
                </template>
              </a-select>
            </a-col>
          </a-collapse-item>
        </a-collapse>
      </a-col>
    </a-row>
    <!-- 启动按钮 -->
    <a-row class="tabs-mrt">
      <a-col>
        <a-space>
          <a-button type="primary" :loading="isRestarted" @click="restartServe">
            <template #icon>
              <icon-poweroff />
            </template>
            <template #default>{{
              isRestarted ? "启停中" : "一键启停"
            }}</template>
          </a-button>
          <a-button type="primary" status="success" :loading="isRestarted" @click="getRegStatus">
            <template #icon>
              <icon-find-replace />
            </template>
            <template #default>查询状态</template>
          </a-button>
          <a-button type="primary" status="success" @click="readRestLogFile">
            <template #icon>
              <icon-find-replace />
            </template>
            <template #default>查询日志</template>
          </a-button>
        </a-space>
      </a-col>
    </a-row>
    <a-row class="tabs-mrt">
      <a-col :span="22" class="tabs-mrt">
        <a-textarea placeholder="查看日志请点击查询按钮" style="overflow-y:auto;height: 200px;" v-model="restartLog" />
      </a-col>
    </a-row>
    <!-- 启动监控 -->
    <a-row class="tabs-mrt">
      <a-col :span="22" class="tabs-mrt">
        <a-table :columns="regColumns" :data="regData" />
      </a-col>
    </a-row>
  </div>
</template>

<script>
import {
  IconCloud,
  IconRobot,
  IconSave,
  IconCloudDownload,
  IconPoweroff,
  IconCloseCircle,
  IconFindReplace,
} from "@arco-design/web-vue/es/icon";
import { restartServer, getEurkaStatus, readRegisterFile, readServerFile, writeServerFile, writeRegisterFile, readRestLog } from "@/api/index.js";
/**
 * 1.配置化，配置服务器信息：账号密码，支持ssh配置，配置可读可写，初始化时，读取配置  考虑多台服务器部署不同的服务
 * 2.配置化，配置服务主目录，例如：/home/lcpt60/app
 * 3.调用startUp.sh 和 stop.sh  或者 直接调用 restart.sh 但是需要提示需要有restart脚本
 * 4.构想k8s重启模式
 * 5.判断日志
 * 6.TODO:写入本地session，记录数据
 * 7.TODO:密码通过desc进行加密，服务端进行des解密
 */
export default {
  components: {
    IconCloud,
    IconRobot,
    IconSave,
    IconCloudDownload,
    IconPoweroff,
    IconFindReplace,
    IconCloseCircle,
  },
  data() {
    return {
      serverPath: import.meta.env.VITE_BASE_SERVER_URL + "/data/shell/demo/",
      isRestarted: false, // 防止重复点击
      selectMode: "normal",
      fileServeData: [],
      serveCount: 1,
      finaServeData: [],
      serveData: [
        {
          key: 1,
          title: "",
          ip: "",
          port: "",
          username: "",
          password: "",
          server: [],
          serverPath: "",
        },
      ],
      serves: [
        "lib",
        "lcpt-gateway2-host",
        "lcpt-fina-pub-online",
        "lcpt-fina-pub-api",
        "lcpt-fina-pub-batch",
        "lcpt-fina-online-trade",
        "lcpt-fina-online-query",
        "lcpt-web-manager-fina",
        "lcpt-register",
        "lcpt-fina-batch1",
        "lcpt-fina-batch2",
        "lcpt-schedule",
        "lcpt-fina-api",
        "lcpt-gateway2-tcpcomm-bank",
        "lcpt-datax",
        "lcpt-gateway2-bank",
        "lcpt-dxfund-online-trade",
        "lcpt-web-manager-dxfund",
        "lcpt-dxfund-pub-batch",
        "lxpt-dxfund-pub-online",
        "lcpt-dxfund-pub-api",
        "lcpt-dxfund-batch1",
        "lcpt-dxfund-batch2",
        "lcpt-dxfund-online-query",
        "lcpt-dxfund-api",
        "lcpt-web-manager-insure",
        "lcpt-insure-pub-online",
        "lcpt-insure-pub-batch",
        "lcpt-insure-pub-api",
        "lcpt-insure-online",
        "lcpt-insure-batch1",
        "lcpt-insure-batch2",
        "lcpt-insure-api",
      ],
      restartServeData: [],
      registerData: {
        url: "", //注册中心地址
        name: "", //注册中心名，eurka/consul/nacos/zookeeper
      },
      regColumns: [
        {
          title: "服务名",
          dataIndex: "name",
        },
        {
          title: "端口",
          dataIndex: "port",
        },
        {
          title: "所在IP",
          dataIndex: "ipAddr",
        },
        {
          title: "启动状态",
          dataIndex: "status",
        },
      ],
      regData: [],
      restartLog: ""
    };
  },
  mounted() {
    // 远程读取server-json
    readServerFile({
      fileName: "server.json",
    })
      .then((res) => {
        this.serveData = res.data.data;
        this.$toast.open({
          message: "服务器配置文件读取成功",
          type: "success",
          duration: 3000,
          position: "top-right",
        });
      })
      .catch((error) => {
        // console.log(error);
        this.$toast.open({
          message: "配置读取-该功能需要启动后台服务，请检查是否启用后台服务！",
          type: "error",
          duration: 6000,
          position: "top-right",
        });
      });
    // 远程读取register-json
    readRegisterFile({
      fileName: "register.json",
    })
      .then((res) => {
        this.registerData = res.data.data;
        this.$toast.open({
          message: "注册中心配置文件读取成功",
          type: "success",
          duration: 3000,
          position: "top-right",
        });
      })
      .catch((error) => {
        // console.log(error);
        this.$toast.open({
          message: "注册读取-该功能需要启动后台服务，请检查是否启用后台服务！",
          type: "error",
          duration: 6000,
          position: "top-right",
        });
      });
    // this.getRegStatus();
  },
  methods: {
    changeRestartSer() {
      // console.log(this.restartServeData);
    },
    selectAllRestartSer() {
      // console.log(222);
      this.restartServeData = this.serves;
    },
    handleAdd() {
      this.serveCount++;
      this.serveData.push({
        key: this.serveCount,
        title: "名称" + this.serveCount,
        ip: "",
        port: "",
        password: "",
        server: [],
      });
    },
    handleDelete(key) {
      this.serveData = this.serveData.filter((item) => item.key != key);
    },
    testCon() {
      this.finaServeData = this.serveData;
      console.log(this.finaServeData);
    },
    saveCon() {
      // 数组深拷贝
      this.finaServeData = JSON.parse(JSON.stringify(this.serveData));
      let savaData = {
        fileName: "server.json",
        data: this.finaServeData,
      };
      // 保存文件到服务器
      writeServerFile(savaData)
        .then((res) => {
          // console.log(res);
          let data = res.data;
          if (res.status == 200 && data.code == 200) {
            this.$toast.open({
              message: data.msg,
              type: "success",
              duration: 3000,
              position: "top-right",
            });
          } else {
            this.$toast.open({
              message: data.msg,
              type: "error",
              duration: 3000,
              position: "top-right",
            });
          }
        })
        .catch((error) => {
          console.log(error);
          this.$toast.open({
            message: error,
            type: "error",
            duration: 6000,
            position: "top-right",
          });
        });
    },
    saveRegister() {
      // 判空
      if (this.registerData.url == "" || this.registerData.name == "") {
        this.$toast.open({
          message: "注册中心配置有空值！",
          type: "error",
          duration: 6000,
          position: "top-right",
        });
        return;
      }
      let savaData = {
        fileName: "register.json",
        data: this.registerData,
      };
      // 保存文件到服务器
      writeRegisterFile(savaData)
        .then((res) => {
          // console.log(res);
          let data = res.data;
          if (res.status == 200 && data.code == 200) {
            this.$toast.open({
              message: data.msg,
              type: "success",
              duration: 3000,
              position: "top-right",
            });
          } else {
            this.$toast.open({
              message: data.msg,
              type: "error",
              duration: 3000,
              position: "top-right",
            });
          }
        })
        .catch((error) => {
          console.log(error);
          this.$toast.open({
            message: error,
            type: "error",
            duration: 6000,
            position: "top-right",
          });
        });
    },
    genServerIp(server) {
      let result = [];
      server.forEach((element) => {
        let ip = element.ip;
        let serverPath = element.serverPath;
        let username = element.username;
        let port = element.port;
        let password = element.password;
        element.server.forEach((e) => {
          let obj = {
            serverName: e,
            ip: ip,
            serverPath: serverPath,
            username: username,
            port: port,
            password: password,
          };
          result.push(obj);
        });
      });
      return result;
    },
    genServerListIp() {
      let restData = JSON.parse(JSON.stringify(this.restartServeData));
      let serData = JSON.parse(JSON.stringify(this.serveData));
      let serverIP = this.genServerIp(serData);
      // console.log(restData);
      // console.log(serData);
      let pack = [];
      restData.forEach((file) => {
        let fileName = file;
        // 普通服务的遍历
        serverIP.forEach((server) => {
          // console.log(server);
          if (fileName == server.serverName) {
            let obj = {
              ip: server.ip,
              serverName: fileName,
              serverPath: server.serverPath,
              username: server.username,
              port: server.port,
              password: server.password,
            };
            pack.push(obj);
          }
        });
      });
      return pack;
    },
    restartServe() {
      let that = this;
      this.isRestarted = true;
      if (this.restartServeData.length < 1) {
        this.$toast.open({
          message: "请选择需要启停的服务！",
          type: "error",
          duration: 6000,
          position: "top-right",
        });
        this.isRestarted = false;
        return;
      }
      let restSerIp = this.genServerListIp();
      restartServer({
        "mode": this.selectMode,
        "server": restSerIp,
        "type":"restart" // restart devlopy devlopy时，后端自动读取文件
      });
      setTimeout(function () {
        that.isRestarted = false;
        that.$toast.open({
          message: "服务启停成功，查看日志请点击查询日志按钮",
          type: "warning",
          duration: 6000,
          position: "top-right",
        });
      }, 5 * 1000);//延迟5000毫米
    },
    readRestLogFile() {
      this.restartLog = ""; // 先清空暂存的
      readRestLog({
        fileName: "restart.log",
      })
        .then((res) => {
          this.restartLog = res.data.data;
          this.$toast.open({
            message: "日志文件读取成功",
            type: "success",
            duration: 3000,
            position: "top-right",
          });
        })
        .catch((error) => {
          // console.log(error);
          this.$toast.open({
            message: error,
            type: "error",
            duration: 6000,
            position: "top-right",
          });
        });
    },
    getRegStatus(type = "eurka") {
      // console.log(type);
      // TODO:根据不同的类型去查询，目前没找到consul的实现
      // 点击了请求，先清理已有的数据
      this.regData = [];
      getEurkaStatus(null)
        .then((res) => {
          // console.log(res);
          // 请求到数据，然后封装数据进行展示
          // 获取到 application 数组
          let application = res.data.data.applications.application;
          // console.log(application);
          // 获取字段 ,封装在数据中
          application.forEach((element) => {
            // 定义临时的对象
            let obj = {
              name: element.name,
              port: element.instance[0].port.$,
              ipAddr: element.instance[0].ipAddr,
              status: element.instance[0].status,
            };
            this.regData.push(obj);
          });
        })
        .catch((error) => {
          console.log(error);
          this.$toast.open({
            message: error,
            type: "error",
            duration: 6000,
            position: "top-right",
          });
        });
    },
  },
};
</script>

<style scoped>
.tabs-mrt {
  margin: 10px 0;
}
</style>
